//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_dev_container_api_serv

import (
	"context"

	"atomgit.com/openlinksaas/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas/api-server/config"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/dev_container_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/dev_container_api"
	"go.mongodb.org/mongo-driver/mongo"
)

type DevContainerAdminApiImpl struct {
	dev_container_api.UnimplementedDevContainerAdminApiServer
	adminCfg *config.AdminCfg
}

func NewDevContainerAdminApiImpl(adminCfg *config.AdminCfg) *DevContainerAdminApiImpl {
	return &DevContainerAdminApiImpl{adminCfg: adminCfg}
}

func (apiImpl *DevContainerAdminApiImpl) AddPackage(ctx context.Context, req *dev_container_api.AdminAddPackageRequest) (*dev_container_api.AdminAddPackageResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &dev_container_api.AdminAddPackageResponse{
			Code:   dev_container_api.AdminAddPackageResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &dev_container_api.AdminAddPackageResponse{
			Code:   dev_container_api.AdminAddPackageResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.DevContainerPerm.AddPackage {
		return &dev_container_api.AdminAddPackageResponse{
			Code:   dev_container_api.AdminAddPackageResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := dev_container_dao.PkgDao.Exist(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if exist {
		return &dev_container_api.AdminAddPackageResponse{
			Code: dev_container_api.AdminAddPackageResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dev_container_dao.PkgDao.Insert(sessCtx, &dev_container_dao.PkgDbItem{
			Name:      req.PackageName,
			PluginUrl: req.PluginUrl,
		})
		if err != nil {
			return nil, err
		}
		return &dev_container_api.AdminAddPackageResponse{
			Code: dev_container_api.AdminAddPackageResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*dev_container_api.AdminAddPackageResponse), nil
}

func (apiImpl *DevContainerAdminApiImpl) RemovePackage(ctx context.Context, req *dev_container_api.AdminRemovePackageRequest) (*dev_container_api.AdminRemovePackageResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &dev_container_api.AdminRemovePackageResponse{
			Code:   dev_container_api.AdminRemovePackageResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &dev_container_api.AdminRemovePackageResponse{
			Code:   dev_container_api.AdminRemovePackageResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.DevContainerPerm.RemovePackage {
		return &dev_container_api.AdminRemovePackageResponse{
			Code:   dev_container_api.AdminRemovePackageResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	exist, err := dev_container_dao.PkgDao.Exist(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &dev_container_api.AdminRemovePackageResponse{
			Code: dev_container_api.AdminRemovePackageResponse_CODE_OK,
		}, nil
	}
	count, err := dev_container_dao.PkgVerDao.Count(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if count > 0 {
		return &dev_container_api.AdminRemovePackageResponse{
			Code:   dev_container_api.AdminRemovePackageResponse_CODE_HAS_VERSION,
			ErrMsg: "需先清空软件包版本",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dev_container_dao.PkgDao.Remove(sessCtx, req.PackageName)
		if err != nil {
			return nil, err
		}
		return &dev_container_api.AdminRemovePackageResponse{
			Code: dev_container_api.AdminRemovePackageResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*dev_container_api.AdminRemovePackageResponse), nil
}

func (apiImpl *DevContainerAdminApiImpl) AddPackageVersion(ctx context.Context, req *dev_container_api.AdminAddPackageVersionRequest) (*dev_container_api.AdminAddPackageVersionResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code:   dev_container_api.AdminAddPackageVersionResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code:   dev_container_api.AdminAddPackageVersionResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.DevContainerPerm.AddPackageVersion {
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code:   dev_container_api.AdminAddPackageVersionResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := dev_container_dao.PkgDao.Exist(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code:   dev_container_api.AdminAddPackageVersionResponse_CODE_NO_PACKAGE,
			ErrMsg: "软件包不存在",
		}, nil
	}
	exist, err = dev_container_dao.PkgVerDao.Exist(ctx, req.PackageName, req.Version)
	if err != nil {
		return nil, err
	}
	if exist {
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code: dev_container_api.AdminAddPackageVersionResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dev_container_dao.PkgVerDao.Insert(sessCtx, &dev_container_dao.PkgVerDbItem{
			PkgName: req.PackageName,
			Version: req.Version,
		})
		if err != nil {
			return nil, err
		}
		return &dev_container_api.AdminAddPackageVersionResponse{
			Code: dev_container_api.AdminAddPackageVersionResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*dev_container_api.AdminAddPackageVersionResponse), nil
}

func (apiImpl *DevContainerAdminApiImpl) RemovePackageVersion(ctx context.Context, req *dev_container_api.AdminRemovePackageVersionRequest) (*dev_container_api.AdminRemovePackageVersionResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code:   dev_container_api.AdminRemovePackageVersionResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code:   dev_container_api.AdminRemovePackageVersionResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.DevContainerPerm.RemovePackageVersion {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code:   dev_container_api.AdminRemovePackageVersionResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := dev_container_dao.PkgDao.Exist(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code:   dev_container_api.AdminRemovePackageVersionResponse_CODE_NO_PACKAGE,
			ErrMsg: "软件包不存在",
		}, nil
	}
	exist, err = dev_container_dao.PkgDao.Exist(ctx, req.PackageName)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code:   dev_container_api.AdminRemovePackageVersionResponse_CODE_NO_PACKAGE,
			ErrMsg: "软件包不存在",
		}, nil
	}
	exist, err = dev_container_dao.PkgVerDao.Exist(ctx, req.PackageName, req.Version)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code: dev_container_api.AdminRemovePackageVersionResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dev_container_dao.PkgVerDao.Remove(sessCtx, req.PackageName, req.Version)
		if err != nil {
			return nil, err
		}
		return &dev_container_api.AdminRemovePackageVersionResponse{
			Code: dev_container_api.AdminRemovePackageVersionResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*dev_container_api.AdminRemovePackageVersionResponse), nil
}
